package edu.whut.mall.portal.async;

import edu.whut.mall.mapper.GroupBuyOrderMapper;
import edu.whut.mall.mapper.GroupBuyRecordMapper;
import edu.whut.mall.mapper.GroupBuyRecordUserMapper;
import edu.whut.mall.model.*;
import edu.whut.mall.portal.enums.GroupBuyRecordStatusEnum;
import edu.whut.mall.portal.enums.GroupBuyUserTypeEnum;
import edu.whut.mall.portal.enums.OrderStatusEnum;
import edu.whut.mall.portal.mapper.GroupBuyOrderCustomMapper;
import edu.whut.mall.portal.mapper.GroupBuyRuleCustomMapper;
import edu.whut.mall.portal.mapper.RobotCustomMapper;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Random;
import java.util.stream.Collectors;

/**
 * @program: d9lab-mall
 * @description: 团购异步处理任务
 * @author: Wayne
 * @create: 2020-05-24 20:52
 **/
@Component
@Slf4j
@RequiredArgsConstructor
public class GroupBuyAsyncService {

    private final GroupBuyOrderMapper groupBuyOrderMapper;

    private final GroupBuyRecordUserMapper groupBuyRecordUserMapper;

    private final GroupBuyRecordMapper groupBuyRecordMapper;

    private final GroupBuyOrderCustomMapper groupBuyOrderCustomMapper;

    private final GroupBuyRuleCustomMapper groupBuyRuleCustomMapper;

    private final RobotCustomMapper robotCustomMapper;

    @Async
    @Transactional
    public void SuccessGroupBuyOrder(Long groupBuyRecordId){
        log.info("团购号{}完成团购",groupBuyRecordId);
        //结束此次团购记录
        Date now = new Date();
        GroupBuyRecord record = groupBuyRecordMapper.selectByPrimaryKey(groupBuyRecordId);
        record.setEndTime(now);
        record.setUpdateTime(now);
        record.setStatus(GroupBuyRecordStatusEnum.GROUP_BUY_SUCCESS.getCode());
        groupBuyRecordMapper.updateByPrimaryKeySelective(record);
        groupBuyRuleCustomMapper.updateSuccessGroupBuyCount(record.getGroupBuyRuleId());
        //修改每个用户的订单状态
        GroupBuyRecordUserExample RecordUserExample = new GroupBuyRecordUserExample();
        RecordUserExample.createCriteria().andRecordIdEqualTo(groupBuyRecordId);
        List<GroupBuyRecordUser> userList = groupBuyRecordUserMapper.selectByExample(RecordUserExample);
        List<String> orderNoList = userList.stream().map(GroupBuyRecordUser::getOrderId).collect(Collectors.toList());
        GroupBuyOrderExample orderExample = new GroupBuyOrderExample();
        orderExample.createCriteria().andOrderNoIn(orderNoList);
        List<GroupBuyOrder> orderList = groupBuyOrderMapper.selectByExample(orderExample);
        //更新团购订单为待发货
        orderList.forEach(order ->{
            log.info("订单号{}修改为待发货", order.getOrderNo());
            GroupBuyOrder e = new GroupBuyOrder();
            e.setOrderNo(order.getOrderNo());
            e.setOrderStatus(OrderStatusEnum.NOT_SHIPPED.getCode());
            e.setUpdateTime(now);
            groupBuyOrderMapper.updateByPrimaryKeySelective(e);
            groupBuyRuleCustomMapper.updateUserRuleCount(order.getUserId(), record.getGroupBuyRuleId());
        });


    }

    @Async
    @Scheduled(cron = "0 0/1 * * * ? ")
    @Transactional
    public void processExpireGroupBuyOrder() {
        List<GroupBuyRecord> expireGroupBuyRecords = groupBuyOrderCustomMapper.getExpireGroupBuyOrders();
        if (CollectionUtils.isNotEmpty(expireGroupBuyRecords)) {
            log.info("***********开始处理过期但没有成功的团购**********");
            expireGroupBuyRecords.forEach(record -> {
                log.info("团购记录号{}", record.getId());
                GroupBuyRecordUserExample RecordUserExample = new GroupBuyRecordUserExample();
                RecordUserExample.createCriteria().andRecordIdEqualTo(record.getId());
                List<GroupBuyRecordUser> userList = groupBuyRecordUserMapper.selectByExample(RecordUserExample);
                List<String> orderNoList = userList.stream().map(GroupBuyRecordUser::getOrderId).collect(Collectors.toList());
                GroupBuyOrderExample orderExample = new GroupBuyOrderExample();
                orderExample.createCriteria().andOrderNoIn(orderNoList);
                List<GroupBuyOrder> orderList = groupBuyOrderMapper.selectByExample(orderExample);
                //更新团购订单为待发货
                orderList.forEach(order -> {
                    log.info("订单号{}修改为待发货", order.getOrderNo());
                    GroupBuyOrder e = new GroupBuyOrder();
                    e.setOrderNo(order.getOrderNo());
                    e.setOrderStatus(OrderStatusEnum.NOT_SHIPPED.getCode());
                    e.setUpdateTime(record.getExpireTime());
                    groupBuyOrderMapper.updateByPrimaryKeySelective(e);
//                    groupBuyRuleCustomMapper.updateUserRuleCount(order.getUserId(), record.getGroupBuyRuleId());
                });
                //机器人拼单
                int lackPeopleCount = record.getSuccessNumber() - userList.size();
                robotJoinRecord(lackPeopleCount, record.getId());
                //结束此次团购记录
                record.setEndTime(record.getExpireTime());
                record.setUpdateTime(record.getExpireTime());
                record.setCurrentNumber(record.getSuccessNumber());
                record.setStatus(GroupBuyRecordStatusEnum.GROUP_BUY_SUCCESS.getCode());
                groupBuyRecordMapper.updateByPrimaryKeySelective(record);
                groupBuyRuleCustomMapper.updateSuccessGroupBuyCount(record.getGroupBuyRuleId());
            });
        }
    }

    /**
     * 机器人拼团
     * @param lackPeopleCount 差的人数
     * @return
     */
    private void robotJoinRecord(Integer lackPeopleCount, Long recordId) {
        int totalCount = robotCustomMapper.countAllRobots();
        int offset = new Random().nextInt(totalCount - lackPeopleCount - 1);
        List<Robot> robotList = robotCustomMapper.selectSpecificQuantityRobots(offset, lackPeopleCount);
        List<GroupBuyRecordUser> robotRecordUser = new ArrayList<>(robotList.size());
        int index = 0;
        for (Robot robot : robotList) {
            GroupBuyRecordUser groupBuyRecordUser = new GroupBuyRecordUser();
            groupBuyRecordUser.setRecordId(recordId);
            groupBuyRecordUser.setUsername(robot.getRobotName());
            groupBuyRecordUser.setUserPic(robot.getRobotPic());
            groupBuyRecordUser.setUserType(GroupBuyUserTypeEnum.GROUP_BUY_JOIN.getCode());
            groupBuyRecordUser.setOrderId("robotOrderId--" + index ++);
            robotRecordUser.add(groupBuyRecordUser);
        }
        robotCustomMapper.batchInsertRobot(robotRecordUser);
    }

}
